package com.sgb.kjwl.view.ui.adapter.base

import android.view.View
import com.sgb.kjwl.view.ui.adapter.base.SimpleViewHolder

abstract class RecyclerViewListExpandable<G : RecyclerContract.ExpandableNode, C : RecyclerContract.ExpandableNode>
    : HDBaseAdapter<SimpleViewHolder>(),
        RecyclerContract.Expandable,
        RecyclerContract.ExpandableContract<MutableList<G>, G, C> {
    var data = mutableListOf<G>()

    /**
     * Group 长短点击事件
     */
    var onGroupItemClickListeners: RecyclerContract.OnGroupItemClickListener? = null
    var onGroupItemLongClickListener: RecyclerContract.OnGroupItemLongClickListener? = null

    /**
     * Child 长短点击事件
     */
    var onChildItemClickListener: RecyclerContract.OnChildItemClickListener? = null
    var onChildItemLongClickListener: RecyclerContract.OnChildItemLongClickListener? = null

    lateinit var expandableHelper: ExpandableHelper

    init {
        initExpandableHelper()
    }

    private fun initExpandableHelper() {
        expandableHelper = ExpandableHelper(this)
    }

    override fun onBindDataViewHolder(holder: SimpleViewHolder, position: Int) {
        val lViewType = getItemViewType(position)
        val (first, second) = expandableHelper.indexOfPosition(position)
        if (lViewType > 0) {
            onBindChildViewHolder(holder, first, second)
        } else {
            onBindGroupViewHolder(holder, first)
        }
    }

    override fun getLayoutResId(viewType: Int): Int {
        return if (viewType > 0) {
            getChildLayoutResId(viewType)
        } else {
            getGroupLayoutResId(viewType)
        }
    }

    override fun getItemId(position: Int): Long {
        val (first, second) = expandableHelper.indexOfPosition(position)
        return if (getItemViewType(position) > 0) {
            getChildItemId(first, second)
        } else {
            getGroupItemId(first)
        }
    }

    override fun getDataItemCount(): Int {
        return expandableHelper.getItemCount()
    }

    override fun getDataItemViewType(position: Int): Int {
        val (first, second) = expandableHelper.indexOfPosition(position)
        return if (second == -1) {
            checkParameters(-getGroupItemViewType(first))
        } else {
            checkParameters(getChildItemViewType(first, second))
        }
    }

    protected open fun getChildItemViewType(groupPosition: Int, childPosition: Int): Int {
        return 1
    }

    protected fun getGroupItemViewType(groupPosition: Int): Int {
        return 1
    }

    protected fun getGroupItemId(groupPosition: Int): Long {
        return -1
    }

    protected fun getChildItemId(groupPosition: Int, childPosition: Int): Long {
        return -1
    }

    protected abstract fun onBindGroupViewHolder(holder: SimpleViewHolder?, groupPosition: Int)
    protected abstract fun onBindChildViewHolder(holder: SimpleViewHolder?, groupPosition: Int, childPosition: Int)
    protected abstract fun getGroupLayoutResId(viewType: Int): Int
    protected abstract fun getChildLayoutResId(viewType: Int): Int

    /**
     * 点击事件
     *
     * @param view View
     * @param position 位置
     */
    override fun onItemClick(view: View?, position: Int) {
        if (position < 0 || position > getDataItemCount()) {
            return
        }
        val (first, second) = expandableHelper.indexOfPosition(position)
        if (getItemViewType(position) > 0) {
            onChildItemClickListener?.onChildItemClick(view, first, second)
        } else if (getItemViewType(position) < 0) {
            onGroupItemClickListeners?.onGroupItemClick(view, first)
        }
    }

    override fun onItemLongClick(view: View?, position: Int) {
        if (position < 0 || position > getDataItemCount()) {
            return
        }
        val ofValue = expandableHelper.indexOfValue(position)
        if (ofValue < 0) {
            val (first, second) = expandableHelper.indexOfPosition(position)
            onChildItemLongClickListener?.onChildItemLongClick(view, first, second)
        } else if (ofValue > 0) {
            onGroupItemLongClickListener?.onGroupItemLongClick(view, ofValue)
        }
    }

    override fun onRefresh(ts: MutableList<G>?) {
        if (ts == null) {
            data.clear()
            notifyDataSetChanged()
            expandableHelper.notifyPositionChanged()
        } else {
            data.clear()
            data.addAll(ts)
            notifyDataSetChanged()
            expandableHelper.notifyPositionChanged()
        }
    }

    override fun onLoad(ts: MutableList<G>, groupPosition: Int, position: Int) {
        val itemCount = expandableHelper.getItemCount()
        data.addAll(ts)
        notifyItemRangeInserted(itemCount, ts.size)
        expandableHelper.notifyPositionChanged()
    }

    /**
     * check View Type
     * @param viewType Vaue
     * @return value
     */
    private fun checkParameters(viewType: Int): Int {
        if (viewType == 0) {
            throw NullPointerException("viewType!=0!")
        }
        return viewType
    }

    override fun getChildItem(groupPosition: Int, childPosition: Int): C? {
        val expandableNode = getGroupItem(groupPosition)?.childNode?.get(childPosition)
        return if (expandableNode == null) null else expandableNode as C
    }

    override fun getChild(groupPosition: Int): List<C>? {
        val childNode = getGroupItem(groupPosition)?.childNode
        return if (childNode == null) null else childNode as List<C>
    }

    override fun getGroupItem(groupPosition: Int): G? {
        if (data.includeIndex(groupPosition)) {
            return data[groupPosition]
        }
        return null
    }


    /**
     * 展开某组
     */
    fun expandGroup(groupPosition: Int) {
        val groupItem = getGroupItem(groupPosition) ?: return
        if (groupItem.isSupportExpandable && !groupItem.isExpandable) {
            groupItem.isExpandable = !groupItem.isExpandable
            var i = expandableHelper.indexOfItemInPosition(groupPosition, 0)
            val size = groupItem.childNode.size
            notifyItemChanged(i)
            if (size != 0) {
                i += 1
                notifyItemRangeInserted(i, size)
                val i1 = getDataItemCount() - i
                notifyItemRangeChanged(i, i1)
                expandableHelper.indexOfGroupPosition(groupPosition)
            }
        }
    }

    /**
     * 收缩某组
     */
    fun collapseGroup(groupPosition: Int) {
        val groupItem = getGroupItem(groupPosition) ?: return
        if (groupItem.isSupportExpandable && groupItem.isExpandable) {
            groupItem.isExpandable = !groupItem.isExpandable
            var i = expandableHelper.indexOfItemInPosition(groupPosition, 0)
            val size = groupItem.childNode.size
            notifyItemChanged(i)
            if (size != 0) {
                i += 1
                notifyItemRangeRemoved(i, size)
                val i1 = getDataItemCount() - i - size
                notifyItemRangeChanged(i, i1)
                expandableHelper.indexOfGroupPosition(groupPosition)
            }
        }
    }

    override fun getGroupCount(): Int {
        return data.size
    }

    override fun getChildrenCount(groupPosition: Int): Int {
        val groupItem = getGroupItem(groupPosition) ?: return 0
        return if (groupItem.isSupportExpandable && groupItem.isExpandable) groupItem.childNode.size else 0
    }


}

fun <T> MutableList<T>.includeIndex(index: Int): Boolean {
    if (index < 0 || index > size) {
        return false
    }
    return true
}